#include "stdafx.h"
#include "VideoSettings.h"

#include "Exception.h"

namespace Cvekas {

// TODO: remove all settings which should not be here: bbufer/depth formats
// TODO: use proper names in antialiasing: 2x, 4x, 16xQS, etc.

VideoSettings::VideoSettings(const std::string& filename)
: SettingsGroup("video", filename)
{
	// Create settings and set default values.
	// No new settings can be added later.

	settings["Renderer"] = SettingValue("Hardware");
	settings["ScreenWidth"] = SettingValue("640");
	settings["ScreenHeight"] = SettingValue("480");
	settings["RefreshRate"] = SettingValue("0");
	settings["Fullscreen"] = SettingValue("0");
	settings["BBufferFormat"] = SettingValue("D3DFMT_X8R8G8B8");
	settings["DepthStencilFormat"] = SettingValue("D3DFMT_D16");
	settings["Antialiasing"] = SettingValue("D3DMULTISAMPLE_NONE");
	settings["VSync"] = SettingValue("0");
	settings["VertexProcessing"] = SettingValue("Hardware");
}

SettingValue& VideoSettings::operator[](const std::string& name)
{
	std::map<std::string, SettingValue>::iterator itr = settings.find(name);

	if(itr == settings.end())
		throw EXCEPTION("No setting named " + name + " in group " + this->name);

	return itr->second;
}

D3DDEVTYPE VideoSettings::getRenderer()
{
	SettingValue& renderer = (*this)["Renderer"];
	std::string str_renderer = renderer;

	if(str_renderer == "Hardware")
		return D3DDEVTYPE_HAL;

	if(str_renderer == "Software")
		return D3DDEVTYPE_REF;

	throw EXCEPTION("Bad setting Renderer value: " + str_renderer);
}

D3DFORMAT VideoSettings::getBBufferFormat()
{
	SettingValue& back_buffer = (*this)["BBufferFormat"];
	std::string str_back_buffer = back_buffer;

	if(str_back_buffer == "D3DFMT_UNKNOWN")
		return D3DFMT_UNKNOWN;

	if(str_back_buffer == "D3DFMT_X8R8G8B8")
		return D3DFMT_X8R8G8B8;

	if(str_back_buffer == "D3DFMT_A8R8G8B8")
		return D3DFMT_A8R8G8B8;

	if(str_back_buffer == "D3DFMT_R5G6B5")
		return D3DFMT_R5G6B5;

	throw EXCEPTION("Bad setting BBufferFormat value: " + str_back_buffer);
}

D3DFORMAT VideoSettings::getDepthStencilFormat()
{
	SettingValue& depth_stencil = (*this)["DepthStencilFormat"];
	std::string str_depth_stencil = depth_stencil;

	if(str_depth_stencil == "D3DFMT_D16")
		return D3DFMT_D16;

	if(str_depth_stencil == "D3DFMT_D24S8")
		return D3DFMT_D24S8;

	if(str_depth_stencil == "D3DFMT_D24X8")
		return D3DFMT_D24X8;

	throw EXCEPTION("Bad setting DepthStencilFormat value: " + str_depth_stencil);
}

D3DMULTISAMPLE_TYPE VideoSettings::getAntialiasing()
{
	SettingValue& antialiasing = (*this)["Antialiasing"];
	std::string str_antialiasing = antialiasing;

	if(str_antialiasing == "D3DMULTISAMPLE_NONE")
		return D3DMULTISAMPLE_NONE;

	if(str_antialiasing == "D3DMULTISAMPLE_NONMASKABLE")
		return D3DMULTISAMPLE_NONMASKABLE;

	if(str_antialiasing == "D3DMULTISAMPLE_2_SAMPLES")
		return D3DMULTISAMPLE_2_SAMPLES;

	if(str_antialiasing == "D3DMULTISAMPLE_4_SAMPLES")
		return D3DMULTISAMPLE_4_SAMPLES;

	if(str_antialiasing == "D3DMULTISAMPLE_6_SAMPLES")
		return D3DMULTISAMPLE_6_SAMPLES;

	if(str_antialiasing == "D3DMULTISAMPLE_8_SAMPLES")
		return D3DMULTISAMPLE_8_SAMPLES;

	if(str_antialiasing == "D3DMULTISAMPLE_16_SAMPLES")
		return D3DMULTISAMPLE_16_SAMPLES;

	throw EXCEPTION("Bad setting Antialiasing value: " + str_antialiasing);
}

DWORD VideoSettings::getVertexProcessing()
{
	SettingValue& vertex_processing = (*this)["VertexProcessing"];
	std::string str_vertex_processing = vertex_processing;

	if(str_vertex_processing == "Hardware")
		return D3DCREATE_HARDWARE_VERTEXPROCESSING;

	if(str_vertex_processing == "Software")
		return D3DCREATE_SOFTWARE_VERTEXPROCESSING;

	throw EXCEPTION("Bad setting VertexProcessing value: " + str_vertex_processing);

}

DWORD VideoSettings::getPresentInterval()
{
	if(static_cast<bool>((*this)["VSync"]) == true)
		return D3DPRESENT_INTERVAL_ONE;
	return D3DPRESENT_INTERVAL_IMMEDIATE;
}

} // namespace
	





